#!/usr/bin/env ruby
# This class is used to calculate the time elapsed between two timestamp
# and convert it into a more readable form.
class RedBook::TimeCalc
	
	SECOND = 1
	MINUTE = SECOND*60
	HOUR = MINUTE*60
	DAY = HOUR*24
	WEEK = DAY*7
	MONTH = DAY*30
	YEAR = DAY*365

	attr_reader :duration

	# Create a new TimeCalc object by passing a duration or two timestamps.
	# 
	# * If two timestamps are passed, TimeCalc will calculate the differencn and convert it to a more readable form
	# * If a duration (in seconds) is passed, TimeCalc will convert it to a more readable form
	def initialize(first, last=nil)
		@text = ""
		@elements = [[YEAR, 'year'], [MONTH, 'month'],
								[WEEK, 'week'], [DAY, 'day'],
								[HOUR, 'hour'], [MINUTE, 'minute'],
								[SECOND, 'second']]
		@result = {}
		# if only one argument passed, it is assumed to be the duration
		@duration = (last) ? last.to_i - first.to_i : first
		calculate(duration)
		compact
		format
	end

	# Return the duration in readable form, e.g. <i>2 minutes and 47 seconds</i>
	def to_s
		@text
	end

	# Return the duration in seconds, e.g. <i>167</i>
	def to_i
		@duration
	end

	private

	def compact
		@result.delete_if { |k, v| v == 0}
	end

	def calculate(seconds, count=0)
		constant, item = @elements[count]
		div, mod = seconds.divmod(constant)
		@result[eval(":#{item}")] = div
		calculate(mod, count+1) unless count >= @elements.length-1
	end

	def format
		count = 0
		@elements.each_index do |i|
			value = @result[eval(":#{@elements[i][1]}")]
			name = @elements[i][1]
			if value then 
				plural = (value >= 2) ? 's' : ''
				if (count == @result.length-1) then 
					sep = '.'
				elsif (count == @result.length-2) then
					sep = ' and '
				else
					sep = ', '
				end
				count+=1
				@text += "#{value} #{name}#{plural}#{sep}"
			end
		end			
	end


end
